package com.atom.module.document.ui;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.atom.module.document.Document;
import com.atom.module.document.R;
import com.atom.module.document.helper.BitmapHelper;
import com.atom.module.document.helper.DocumentHelper;
import com.atom.module.document.helper.PointHelper;
import com.atom.module.document.utils.DocumentUtils;
import com.atom.module.document.utils.FileUtil;
import com.atom.module.document.view.banner.NumIndicator;
import com.atom.module.document.view.recycler.Adapter;
import com.atom.module.image.filter.Image;
import com.atom.module.logger.Logger;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestOptions;
import com.youth.banner.Banner;
import com.youth.banner.adapter.BannerAdapter;
import com.youth.banner.config.IndicatorConfig;
import com.youth.banner.listener.OnPageChangeListener;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.internal.observers.BlockingBaseObserver;
import io.reactivex.schedulers.Schedulers;

/**
 * All rights Reserved, Designed By www.rongdasoft.com
 *
 * @version V1.0
 * @Title: SingleHandleActivity
 * @Description:
 * @author: wuyongzheng
 * @date: 2022/3/28
 * @Copyright: 2022/3/28 www.rongdasoft.com Inc. All rights reserved.
 */
public class MoreHandleActivity extends AbstractAppCompatActivity {

    private final DocumentBannerAdapter documentAdapter = new DocumentBannerAdapter();
    private String documentName;
    private String documentPath; // 不为null 说明是有路径,
    private MoreEntryFilterEntry currentFilter;
    private final Adapter.Subject<MoreEntryFilterEntry> filterAdapter = new Adapter.Subject<MoreEntryFilterEntry>(new Adapter.AbstractListener<MoreEntryFilterEntry>() {
        @Override
        public void onItemClick(View view, Adapter.Subject<MoreEntryFilterEntry> adapter, Adapter.ViewHolder<MoreEntryFilterEntry> viewHolder, MoreEntryFilterEntry filter) {
            super.onItemClick(view, adapter, viewHolder, filter);
            Document.Entry entry = filter.getEntry();
            if (entry == null) {
                return;
            }
            if (filter.isSelect()) return;
            for (MoreEntryFilterEntry item : adapter.getItems()) {
                item.setSelect(false);
            }
            filter.setSelect(true);

            view(R.id.applyFilterToAll, (PickView<CheckBox>) radioButton -> {
                if (radioButton.isSelected()) {
                    currentFilter = filter;
                }
            });

            adapter.notifyDataSetChanged();

            entry.setFilterWrapper(filter.getFilterWrapper());
            int i = Document.getDocument().indexOf(entry);
            Logger.e("onItemClick %s", i);
            documentAdapter.notifyItemChanged(i);
        }
    }) {

        @Override
        protected int getItemViewType(int position, MoreEntryFilterEntry filter) {
            return R.layout.item_filter;
        }

        @Override
        public Adapter.ViewHolder<MoreEntryFilterEntry> onCreateViewHolder(View contentView, int viewType) {
            return new FilterViewHolder(contentView);
        }
    };

    private void initParam(Bundle savedInstanceState) {
        Intent intent = getIntent();
        if (intent == null) {
            finish();
            return;
        }
        documentPath = intent.getStringExtra(DocumentHelper.document_path_param);
        documentName = intent.getStringExtra(DocumentHelper.document_name_param);
        if (TextUtils.isEmpty(documentName)) {
            documentName = String.format("荣大智慧云_%s", System.currentTimeMillis());
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_more_handle);
        initParam(savedInstanceState);
        view(R.id.documentName, (PickView<EditText>) v -> {
            v.setText(documentName);
            v.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    documentName = s.toString();
                }
            });
        });
        // 拍照替换
        view(R.id.cameraToReplaceLayoutView, v -> {
            v.setOnClickListener(v1 -> replaceDocument());
        });
        // 相片左转
        view(R.id.moreTurnLeftLayoutView, v -> {
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    view(R.id.autoDocumentViewList, (PickView<Banner<Document.Entry, DocumentBannerAdapter>>) view -> {
                        int currentItem = view.getCurrentItem();
                        Document.Entry data = documentAdapter.getData(currentItem);
                        // 获取当前选择前的 宽高
                        Document.Param param = data.getParam();
                        // 用该宽高对当前的切割点进行旋转
                        data.setPoints(PointHelper.rotatePoint(param, -90, data.getPoints()));
                        // 保存
                        data.setRotate(-90);
                        // 刷新
                        documentAdapter.notifyItemChanged(currentItem);
                    });
                }
            });
        });
        // 照片预览
        view(R.id.autoDocumentViewList, (PickView<Banner<Document.Entry, DocumentBannerAdapter>>) view -> {
            view.setAdapter(documentAdapter, false);
            documentAdapter.setDatas(Document.getDocument());
            documentAdapter.setOnBannerListener((data, position) -> {
                if (data == Document.Entry.EMPTY) {
                    onBackPressed();
                }
            });
            view.setIndicator(new NumIndicator(this));
            view.addOnPageChangeListener(new OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                }

                @SuppressLint("NotifyDataSetChanged")
                @Override
                public void onPageSelected(int position) {
                    Document.Entry data = documentAdapter.getData(position);
                    view(R.id.applyFilterToAll, (PickView<CheckBox>) radioButton -> {
                        if (radioButton.isSelected()) {
                            if (currentFilter != null && data.getFilterWrapper() != currentFilter.getFilterWrapper()) {
                                data.setFilterWrapper(currentFilter.filterWrapper);
                                documentAdapter.notifyItemChanged(position);
                            }
                        }
                    });

                    view(R.id.filterLayout, layout -> {
                        toggleViewClickEnabled(data != Document.Entry.EMPTY);
                        if (layout.getVisibility() == View.GONE) return;
                        layout.setVisibility(data == Document.Entry.EMPTY ? View.INVISIBLE : View.VISIBLE);
                        if (layout.getVisibility() == View.VISIBLE) {
                            for (MoreEntryFilterEntry item : filterAdapter.getItems()) {
                                item.setEntry(data);
                            }
                            filterAdapter.notifyDataSetChanged();
                        }
                    });
                }

                @Override
                public void onPageScrollStateChanged(int state) {

                }
            });
            view.setIndicatorGravity(IndicatorConfig.Direction.CENTER);
            view.setIndicatorPageChange();
            view.isAutoLoop(false);
            view.setBannerGalleryEffect(50, 10);
        });
        // 关闭滤镜预览
        view(R.id.backFilter, view -> {
            view.setOnClickListener(v -> view(R.id.filterLayout, layout -> {
                layout.setVisibility(View.GONE);
            }));
        });
        // 执行滤镜到所有
        view(R.id.applyFilterToAll, (PickView<CheckBox>) view -> {
            view.setOnClickListener(v -> {
                view.setSelected(!view.isSelected());
                if (view.isSelected()) {
                    for (MoreEntryFilterEntry item : filterAdapter.getItems()) {
                        if (item.isSelect()) {
                            currentFilter = item;
                        }
                    }
                }
            });
        });
        // 自动识别文档
        view(R.id.moreAutoShearLayoutView, view -> {
            view.setOnClickListener(v -> {
                startActivity(new Intent(MoreHandleActivity.this, MoreHandleOnlyShearAndRotateActivity.class));
            });
        });
        //  滤镜按钮打开和关闭
        view(R.id.moreFilterLayoutView, view -> {
            view.setOnClickListener(v -> view(R.id.filterLayout, layout -> {
                layout.setVisibility(View.VISIBLE);
                // 加载滤镜
                view(R.id.autoDocumentViewList, (PickView<Banner<Document.Entry, DocumentBannerAdapter>>) banner -> {
                    Document.Entry data = documentAdapter.getData(banner.getCurrentItem());
                    if (data == Document.Entry.EMPTY) {
                        return;
                    }
                    Logger.e("filterLayout  onGlobalLayout 3");
                    view(R.id.filterRecyclerView, (PickView<RecyclerView>) recyclerView -> {
                        recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext(), RecyclerView.HORIZONTAL, false));
                        recyclerView.setAdapter(filterAdapter);
                        recyclerView.post(() -> {
                            filterAdapter.clear();
                            List<MoreEntryFilterEntry> result = new ArrayList<>();
                            for (Document.FilterWrapper filter : Document.filterWrappers) {
                                result.add(new MoreEntryFilterEntry(filter, data));
                            }
                            filterAdapter.addAll(result);
                        });
                    });
                });
            }));
        });
        // 完成
        view(R.id.finishHandle, view -> view.setOnClickListener(v -> shearDocument()));
    }

    private void shearDocument() {
        // 所有的图片都在 .document路径下
        // 将图片进行复制,从.document路径复制到documentPath指定的路径下的sourceDocument
        // 生成新的Document.Entry对象进行新处理
        if (TextUtils.isEmpty(documentPath)) {
            // 进行重新命名,命名规则使用当前的
            documentPath = DocumentHelper.getDocumentPath(this, DocumentHelper.defaultDocumentName());
        }
        // 进行重新命名,命名规则使用当前的
        String targetDocumentSourcePath = DocumentHelper.getDocumentSourcePath(documentPath);
        String defaultDocumentSourcePath = DocumentHelper.getDocumentSourcePath(this, null);
        List<Document.Entry> document = new ArrayList<>(Document.getDocument());
        if (document.isEmpty()) return;
        List<Document.Entry> result = new ArrayList<>();
        ProgressDialog pdDialog = new ProgressDialog(this);
        pdDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pdDialog.setTitle("条形进度条");
        pdDialog.setMessage("正在下载中……");
        pdDialog.setMax(document.size() - 1); // 有一个结束标识位
        pdDialog.setProgress(0);
        pdDialog.setIndeterminate(false);
        pdDialog.setCancelable(true);
        pdDialog.setOnDismissListener(dialog -> {
            Document.clearDocument();
            ArrayList<Document.EntryWrapper> resultData = new ArrayList<>();
            for (Document.Entry entry : result) {
                if (entry == Document.Entry.EMPTY) {
                    continue;
                }
                resultData.add(entry.toWrapper());
            }
            Intent intent = new Intent();
            intent.putExtra(DocumentHelper.camera_result_array_param, resultData);
            setResult(RESULT_FIRST_USER, intent);
            finish();
        });
        pdDialog.show();
        saveDocument(document, pdDialog, targetDocumentSourcePath, defaultDocumentSourcePath, document.size(), result);
    }

    private void saveDocument(List<Document.Entry> document, ProgressDialog pdDialog,
                              String targetDocumentSourcePath, String defaultDocumentSourcePath,
                              int size, List<Document.Entry> result) {
        Document.Entry entry = document.remove(0);
        if (entry == Document.Entry.EMPTY) {
            pdDialog.dismiss();
            return;
        }
        if (FileUtil.copyFile(entry.getSourcePath(), targetDocumentSourcePath)) {
            if (FileUtil.deleteFile(entry.getSourcePath())) {
                String sourcePath = entry.getSourcePath();
                String replace = sourcePath.replace(defaultDocumentSourcePath, targetDocumentSourcePath);
                Document.Entry entryTarget = new Document.Entry(replace,
                    entry.getFilterWrapper(),
                    entry.getPoints(),
                    entry.getRotate());
                saveDocumentInLocal(entryTarget, new BlockingBaseObserver<File>() {
                    @Override
                    public void onNext(File file) {
                        result.add(entryTarget);
                        Logger.e(file.getAbsolutePath());
                        pdDialog.setProgress(size - document.size());
                        saveDocument(document, pdDialog, targetDocumentSourcePath, defaultDocumentSourcePath, size, result);
                    }

                    @Override
                    public void onError(Throwable e) {
                        result.add(entryTarget);
                        Logger.e(e);
                        pdDialog.setProgress(size - document.size());
                        saveDocument(document, pdDialog, targetDocumentSourcePath, defaultDocumentSourcePath, size, result);
                    }
                });
            }
        }
    }

    private void saveDocumentInLocal(Document.Entry entry, Observer<File> observer) {
        DocumentUtils.shearBitmapByPoints2(DocumentUtils.createFrame(entry.getRotateBitmap()), entry.getPoints())
            .map(bitmap -> {
                if (entry.getFilterWrapper() != Document.FilterWrapper.filter_empty_wrapper) {
                    Image process = entry.getFilterWrapper().filter.process(new Image(bitmap));
                    process.copyPixelsFromBuffer();
                    Bitmap destBitmap = process.destImage;
                    if (destBitmap != null && destBitmap != bitmap) {
                        if (!bitmap.isRecycled()) {
                            bitmap.recycle();
                        }
                        bitmap = destBitmap;
                    }
                }
                File saveFile = DocumentHelper.createFile(entry.createHandlePath(), true);
                try {
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(saveFile));
                    return saveFile;
                } catch (Exception e) {
                    Logger.e(e);
                }
                return null;
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer);
    }

    public void replaceDocument() {
        // TODO 拍照替换
        Intent intent = new Intent(MoreHandleActivity.this, CameraViewActivity.class);
        intent.putExtra(DocumentHelper.camera_result_code_param, 2048);
        startActivityForResult(intent, 2048);
    }


    @SuppressLint("NotifyDataSetChanged")
    @Override
    protected void onResume() {
        super.onResume();
        documentAdapter.notifyDataSetChanged();
    }

    public void toggleViewClickEnabled(boolean isEnabled) {
        view(R.id.cameraToReplaceLayoutView, view -> {
            view.setEnabled(isEnabled);
        });
        view(R.id.moreTurnLeftLayoutView, view -> {
            view.setEnabled(isEnabled);
        });
        view(R.id.moreFilterLayoutView, view -> {
            view.setEnabled(isEnabled);
        });
        view(R.id.moreAutoShearLayoutView, view -> {
            view.setEnabled(isEnabled);
        });
    }

    @Override
    public void onBackPressed() {
        Document.removeDocument(Document.Entry.EMPTY);
        super.onBackPressed();
    }

    //------------------------------------------------------------------------------

    class DocumentBannerAdapter extends BannerAdapter<Document.Entry, ViewHolder> {

        public DocumentBannerAdapter() {
            super(null);
        }

        @Override
        public int getItemViewType(int position) {
            return R.layout.item_more_view_holder;
        }

        @Override
        public ViewHolder onCreateHolder(ViewGroup parent, int viewType) {
            final View inflate = LayoutInflater.from(parent.getContext())
                .inflate(viewType, parent, false);
            return new ViewHolder(inflate);
        }

        @Override
        public void onBindView(ViewHolder holder, Document.Entry data, int position, int size) {
            holder.onBind(data);
        }
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        private final ImageView documentShow;

        private final View defaultView;
        private final View emptyView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            documentShow = itemView.findViewById(R.id.documentShow);
            defaultView = itemView.findViewById(R.id.defaultView);
            emptyView = itemView.findViewById(R.id.emptyView);
            itemView.findViewById(R.id.documentHandle).setOnClickListener(v -> {
                AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
                builder.setTitle("删除此页");
                builder.setMessage("删除后无法恢复,如果效果不佳,可进行拍摄替换");
                builder.setPositiveButton("删除", (dialog, which) -> {
                    Logger.e("删除");
                    Document.Entry data = documentAdapter.getData(getAdapterPosition());
                    if (data == Document.Entry.EMPTY) {
                        return;
                    }
                    if (DocumentHelper.deleteFile(data.getSourcePath())) {
                        data.recycleOriginalBitmap();
                        Document.removeDocument(data);
                        documentAdapter.notifyItemRemoved(getAdapterPosition());
                    }
                });
                builder.setNegativeButton("替换", (dialog, which) -> {
                    Logger.e("替换");
                    replaceDocument();
                });
                builder.setNeutralButton("取消", (dialog, which) -> {
                    dialog.dismiss();
                });
                builder.create().show();
            });
        }

        public void onBind(Document.Entry entry) {
            // initView visit
            defaultView.setVisibility(entry == Document.Entry.EMPTY ? View.GONE : View.VISIBLE);
            emptyView.setVisibility(entry != Document.Entry.EMPTY ? View.GONE : View.VISIBLE);
            if (entry == Document.Entry.EMPTY) return;
            // init filter
            // 改变了进行再次的处理
            Observable.create((ObservableOnSubscribe<Bitmap>) emitter -> {
                // 进行旋转
                Bitmap rotateBitmap = entry.getRotateBitmap();
                //执行滤镜
                if (entry.getFilterWrapper() != Document.FilterWrapper.filter_empty_wrapper) {
                    Image process = entry.getFilterWrapper().filter.process(new Image(rotateBitmap));
                    process.copyPixelsFromBuffer();
                    Bitmap resultBitmap = process.destImage;
                    if (resultBitmap != null && resultBitmap != rotateBitmap) {
                        if (!rotateBitmap.isRecycled()) {
                            rotateBitmap.recycle();
                        }
                        rotateBitmap = resultBitmap;
                    }
                }
                emitter.onNext(rotateBitmap);
                emitter.onComplete();
            }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new BlockingBaseObserver<Bitmap>() {
                    @Override
                    public void onNext(Bitmap bitmap) {
                        // 进行图片的裁切
                        Point[] points = entry.getPoints();
                        if (points != null && points.length == 4) {
                            if (PointHelper.isFullPoint(bitmap, points)) {
                                setDocumentBitmap(entry, bitmap);
                                return;
                            }
                            DocumentUtils.shearBitmapByPoints(DocumentUtils.createFrame(bitmap), entry.getPoints(), new BlockingBaseObserver<Bitmap>() {
                                @Override
                                public void onNext(Bitmap resultBitmap) {
                                    // 展示
                                    setDocumentBitmap(entry, resultBitmap);
                                }

                                @Override
                                public void onError(Throwable e) {
                                    Logger.e(e);
                                    setDocumentBitmap(entry, bitmap);
                                }
                            });
                            return;
                        }
                        setDocumentBitmap(entry, bitmap);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Logger.e(e);
                    }
                });
        }

        public void setDocumentBitmap(Document.Entry entry, Bitmap bitmap) {
            RequestOptions options = new RequestOptions()
                .centerCrop()
                .diskCacheStrategy(DiskCacheStrategy.NONE);
            Glide.with(itemView)
                .load(bitmap)
                .apply(options)
                .transition(DrawableTransitionOptions.withCrossFade())
                .into(documentShow);
        }
    }

    //------------------------------------------------------------------------------

    static class FilterViewHolder extends Adapter.ViewHolder<MoreEntryFilterEntry> {

        private final TextView filterName;
        private final ImageView filterShow;
        private final FrameLayout showLayout;

        public FilterViewHolder(@NonNull View itemView) {
            super(itemView);
            filterName = itemView.findViewById(R.id.filterName);
            filterShow = itemView.findViewById(R.id.filterShow);
            showLayout = itemView.findViewById(R.id.showLayout);
        }

        @Override
        public void onBind(MoreEntryFilterEntry filter) {
            filterName.setText(filter.getFilterWrapper().name);
            Observable.just(filter.getEntry())
                .flatMap((Function<Document.Entry, ObservableSource<Bitmap>>) entry -> {
                    Bitmap bitmap = BitmapHelper.centerSquareScaleBitmap(entry.getOriginalBitmap(), 250);
                    Image process = filter.getFilterWrapper().filter.process(new Image(bitmap));
                    process.copyPixelsFromBuffer();
                    return observer -> observer.onNext(process.destImage);
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new BlockingBaseObserver<Bitmap>() {
                    @Override
                    public void onNext(Bitmap bitmap) {
                        filterShow.setImageBitmap(bitmap);
                    }

                    @Override
                    public void onError(Throwable e) {
                        filterShow.setBackgroundColor(Color.RED);
                    }
                });
            if (filter.isSelect()) {
                filterName.setBackgroundResource(R.color.C0080FF_blue);
                showLayout.setBackgroundResource(R.drawable.bg_blue);
            } else {
                filterName.setBackgroundResource(R.color.C606266);
                showLayout.setBackground(null);
            }
        }
    }

    static class MoreEntryFilterEntry {
        private Document.Entry entry;
        private Document.FilterWrapper filterWrapper;
        private boolean select;

        public MoreEntryFilterEntry(Document.FilterWrapper filterWrapper, Document.Entry entry) {
            this.filterWrapper = filterWrapper;
            this.entry = entry;
            checkSelect();
        }

        public void setEntry(Document.Entry entry) {
            this.entry = entry;
            checkSelect();
        }

        public void checkSelect() {
            this.select = filterWrapper.equals(entry.getFilterWrapper());
        }

        public Document.Entry getEntry() {
            return entry;
        }

        public Document.FilterWrapper getFilterWrapper() {
            return filterWrapper;
        }

        public void setFilterWrapper(Document.FilterWrapper filter) {
            this.filterWrapper = filter;
        }

        public boolean isSelect() {
            return select;
        }

        public void setSelect(boolean select) {
            this.select = select;
        }
    }

    //------------------------------------------------------------------------------

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 2048 && resultCode == 2048) {
            if (data == null) return;
            view(R.id.autoDocumentViewList, (PickView<Banner<Document.Entry, DocumentBannerAdapter>>) view -> {
                int currentShowItemIndex = view.getCurrentItem();
                Document.Entry documentByIndex = Document.getDocumentByIndex(currentShowItemIndex);
                if (documentByIndex == null) return;
                if (DocumentHelper.deleteFile(documentByIndex.getSourcePath())) {
                    if (Document.removeDocument(documentByIndex) != -1) {
                        documentByIndex.recycleOriginalBitmap();
                        Document.Entry newEntry = Document.Entry.defaultEntry(FileUtil.getFilePathByUri(this, data.getData()));
                        Document.addDocument(currentShowItemIndex, newEntry);
                        documentAdapter.notifyItemChanged(currentShowItemIndex);
                    }
                }
            });
        }
    }
}
